#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/debugfs.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/completion.h>
#include <linux/list.h>
#include <linux/kthread.h>
#include <linux/atomic.h>
#include <linux/interrupt.h>

#include "debug_file.h"

#define DEBUGFS_DIR "kspeed"
#define DEBUGFS_FILE "size"

static struct dentry *kspeed_dir;
static struct dentry *size_file;

// debugfs文件写操作 - 创建tasklet执行测试
static ssize_t size_write(struct file *file, const char __user *user_buf, size_t count,
			  loff_t *ppos)
{
	char buf[32];
	int new_size;
	int ret;

	if (count >= sizeof(buf))
		return -EINVAL;

	if (copy_from_user(buf, user_buf, count))
		return -EFAULT;

	buf[count] = '\0';

	ret = kstrtoint(buf, 10, &new_size);
	if (ret)
		return ret;

	if (new_size < 1 || new_size > (1024 * 1024)) {
		pr_err("Invalid size: %u\n", new_size);
		return -EINVAL;
	}

	set_datasize(new_size);

	pr_info("kspeed: test size set to %u bytes\n", new_size);

	performance_test_tasklet(1);

	return count;
}

static const struct file_operations size_fops = {
	.owner = THIS_MODULE,
	.write = size_write,
};

int debug_file_init(void)
{
	int ret;

	kspeed_dir = debugfs_create_dir(DEBUGFS_DIR, NULL);
	if (IS_ERR(kspeed_dir)) {
		pr_err("Failed to create debugfs directory\n");
		return PTR_ERR(kspeed_dir);
	}

	if (!kspeed_dir) {
		pr_err("debugfs directory creation failed\n");
		return -ENOMEM;
	}

	// 创建size文件
	size_file = debugfs_create_file("size", 0644, kspeed_dir, NULL, &size_fops);
	if (IS_ERR(size_file)) {
		pr_err("Failed to create debugfs file\n");
		ret = PTR_ERR(size_file);
		goto cleanup_dir;
	}

	if (!size_file) {
		pr_err("debugfs file creation failed\n");
		ret = -ENOMEM;
		goto cleanup_dir;
	}

	return 0;

cleanup_dir:
	debugfs_remove_recursive(kspeed_dir);
	return ret;
}

void debug_file_exit(void)
{
	// 清理debugfs
	if (kspeed_dir)
		debugfs_remove_recursive(kspeed_dir);
}